/**
 * Note security
 * @author Wangtd
 */
const md5 = require('md5-node');

const config = require('../config.js');
const util = require('./util.js');
const logger = require('./logger.js');

function fetchRememberMeUser(request) {
    if (request.cookies.remember_me) {
        var token = new Buffer(request.cookies.remember_me, 'base64');
        var users = JSON.parse(util.readFileSync(config.workDir + '/users.json'));
        for (var i = 0; i < users.length; i++) {
            if (md5(users[i].email + ':' + users[i].password) == token) {
                request.session.user = users[i];
                break;
            }
        }
    }
}

function hasRequestPermission(request) {
    // permissions of reading and mock tools
    if (config.security.allowedHosts === true) {
        return true;
    } else if (config.security.allowedHosts === false) {
        return false;
    } else {
        return util.find(config.security.allowedHosts, function(host) {
                return request.hostname.indexOf(host) == 0 || request.ip.indexOf(host) == 0;
            }) != null;
    }
}

module.exports = {
    fetchRememberMe: fetchRememberMeUser,
    hasPermission: hasRequestPermission,
    checkPermission: function(excludes) {
        return function(request, response, next) {
            var url = request.originalUrl;
            // check request permission
            if (hasRequestPermission(request)) {
                // allow get method
                var method = request.method;
                if (method == 'GET') {
                    return next();
                }
                // allow exclude paths
                for (var i = 0; i < excludes.length; i++) {
                    if (excludes[i] instanceof RegExp) {
                        if (excludes[i].test(url)) {
                            return next();
                        }
                    } else if (url.indexOf(excludes[i]) == 0) {
                        return next();
                    }
                }
            }
            // check remember me
            if (!request.session.user) {
                logger.info(request, 'Fetch remember me user, url=%s', url);
                fetchRememberMeUser(request);
            }
            // check session user
            if (request.session.user) {
                if (/^(PUT|DELETE)$/.test(method) && request.session.user.role != 'admin') {
                    logger.info(request, 'Forbidden(403), url=%s', url);
                    response.status(403).end();
                } else {
                    return next();
                }
            }
            if (!request.session.user) {
                logger.info(request, 'Unauthorized(401), url=%s', url);
                response.status(401).end();
            }
        };
    }
};
